package com.avecsys.quotemanager.service.supplier;

import java.sql.Blob;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.icefaces.ace.component.fileentry.FileEntryResults.FileInfo;

import com.avecsys.quotemanager.constants.BusinessCodes;
import com.avecsys.quotemanager.dao.common.EnumTransactionStatus;
import com.avecsys.quotemanager.dao.supplier.QuoteTransactionDAO;
import com.avecsys.quotemanager.exception.BusinessException;
import com.avecsys.quotemanager.exception.DAOException;
import com.avecsys.quotemanager.exception.UserSessionNotFoundException;
import com.avecsys.quotemanager.mbeans.core.BaseMBean;
import com.avecsys.quotemanager.pojos.BasePojo;
import com.avecsys.quotemanager.pojos.BuyerMasterPojo;
import com.avecsys.quotemanager.pojos.QuoteTransactionEventsPojo;
import com.avecsys.quotemanager.pojos.QuoteTransactionPojo;
import com.avecsys.quotemanager.pojos.SupplierMasterPojo;
import com.avecsys.quotemanager.utils.TransactionStatus;
import com.avecsys.quotemanager.vo.BuyerVO;
import com.avecsys.quotemanager.vo.QuoteVO;
import com.avecsys.quotemanager.vo.SupplierVO;

public class QuoteTransactionServiceImpl implements QuoteTransactionService
{
	private static final Log log = LogFactory.getLog(QuoteTransactionServiceImpl.class);

	private QuoteTransactionDAO quoteTransactionDAO;

	/**
	 * @return the quoteTransactionDAO
	 */
	public QuoteTransactionDAO getQuoteTransactionDAO()
	{
		return quoteTransactionDAO;
	}

	/**
	 * @param quoteTransactionDAO the quoteTransactionDAO to set
	 */
	public void setQuoteTransactionDAO(QuoteTransactionDAO quoteTransactionDAO)
	{
		this.quoteTransactionDAO = quoteTransactionDAO;
	}

	/**
	 * Method to save the Quote Transaction
	 * 
	 * @param supplierVO
	 * @return TransactionStatus
	 * @throws BusinessException
	 */
	@Override
	public TransactionStatus saveQuoteTransaction(SupplierVO supplierVO) throws BusinessException
	{
		// Initial Transaction state when save operation
		TransactionStatus transactionStatus = new TransactionStatus(
				EnumTransactionStatus.SAVE_FAIL.ordinal());
		QuoteTransactionPojo quoteTransactionPojo = supplierVO.getQuoteTransactionsPojo();
		QuoteTransactionEventsPojo quoteTransactionEventsPojo = supplierVO.getQuoteTransactionEventsPojo();
		quoteTransactionPojo.getQuoteTransactionEventsPojoSet().add(quoteTransactionEventsPojo);
		quoteTransactionEventsPojo.setQuoteTransactionPojo(quoteTransactionPojo);
		// Mark the transaction status as pending
		quoteTransactionPojo.setTransactionStatus(BusinessCodes.QUOTE_EVENT_TRANSACTION_STATUS_PENDING);
		quoteTransactionEventsPojo.setTransactionStatus(BusinessCodes.QUOTE_EVENT_TRANSACTION_STATUS_PENDING);
		try
		{
			FileInfo quoteAttachmentFileInfo = supplierVO.getQuoteAttachmentFileInfo();
			if (quoteAttachmentFileInfo != null)
			{
				quoteTransactionEventsPojo.setFileName(quoteAttachmentFileInfo.getFileName());
				quoteTransactionEventsPojo.setContentType(quoteAttachmentFileInfo.getContentType());
				Blob blobFileContent = quoteTransactionDAO.getBlob(quoteAttachmentFileInfo.getFile());
				quoteTransactionEventsPojo.setFileContent(blobFileContent);
			}
			transactionStatus = quoteTransactionDAO.saveQuoteTransaction(quoteTransactionPojo);
		}
		catch (DAOException e)
		{
			log.error(e);
			throw new BusinessException(e);
		}
		return transactionStatus;
	}

	/**
	 * Method to list all sent quotes to buyer that belong to a Supplier
	 * 
	 * @param supplierMasterPojo
	 * @return List<QuoteTransactionPojo>
	 * @throws BusinessException
	 */
	@Override
	public List<QuoteTransactionPojo> getAllSentQuotes(SupplierMasterPojo supplierMasterPojo)
			throws BusinessException
	{
		try
		{
			return quoteTransactionDAO.findAllSentQuotes(supplierMasterPojo);
		}
		catch (DAOException e)
		{
			log.error(e);
			throw new BusinessException(e);
		}
	}

	/**
	 * Method to list all pending Quote transaction Events for Buyer Action
	 * 
	 * @param buyerMasterPojo
	 * @return List<QuoteTransactionEventsPojo>
	 * @throws BusinessException
	 */
	@Override
	public List<QuoteTransactionEventsPojo> getAllQuoteTransactionEventsForBuyer(
			BuyerMasterPojo buyerMasterPojo) throws BusinessException
	{
		try
		{
			return quoteTransactionDAO.findAllQuoteEventsForBuyerAction(buyerMasterPojo);
		}
		catch (DAOException e)
		{
			log.error(e);
			throw new BusinessException(e);
		}
	}

	/**
	 * Method to get QuoteTransactionEventsPojo instance by event Id
	 * 
	 * @param eventId
	 * @return QuoteTransactionEventsPojo
	 * @throws BusinessException
	 */
	@Override
	public QuoteTransactionEventsPojo getQuoteTransactionEventById(Long eventId)
			throws BusinessException
	{
		try
		{
			return quoteTransactionDAO.findQuoteTransactionEventsById(eventId);
		}
		catch (DAOException e)
		{
			log.error(e);
			throw new BusinessException(e);
		}
	}

	/**
	 * Method to mark the transaction status with appropriate transaction
	 * 
	 * @param buyerVO
	 * @return TransactionStatus
	 */
	@Override
	public TransactionStatus replyQuoteEvent(BuyerVO buyerVO) throws BusinessException
	{
		// Initial Transaction state when save operation
		TransactionStatus transactionStatus = new TransactionStatus(
				EnumTransactionStatus.UPDATE_FAIL.ordinal());
		try
		{
			QuoteTransactionEventsPojo quoteTransactionEventsPojo = buyerVO.getQuoteTransactionEventsPojo();
			quoteTransactionEventsPojo.getQuoteTransactionPojo().setTransactionStatus(
					quoteTransactionEventsPojo.getTransactionStatus());
			transactionStatus = quoteTransactionDAO.updateBuyerReply(quoteTransactionEventsPojo);
		}
		catch (DAOException e)
		{
			throw new BusinessException(e);
		}
		return transactionStatus;
	}

	/**
	 * Method to List all QuoteEvents for a Quote Transaction
	 * 
	 * @param quoteTransactionPojo
	 * @return List<QuoteTransactionEventsPojo>
	 * @throws BusinessException
	 */
	@Override
	public List<QuoteTransactionEventsPojo> getAllQuoteTransactionEvents(
			QuoteTransactionPojo quoteTransactionPojo) throws BusinessException
	{
		try
		{
			return quoteTransactionDAO.findAllQuoteEvents(quoteTransactionPojo);
		}
		catch (DAOException e)
		{
			log.error(e);
			throw new BusinessException(e);
		}
	}

	@Override
	public TransactionStatus createQuoteEvent(QuoteVO quoteVO) throws BusinessException,
			UserSessionNotFoundException
	{
		// Initial Transaction state when save operation
		TransactionStatus transactionStatus = new TransactionStatus(
				EnumTransactionStatus.BATCH_SUCCESS.ordinal());
		try
		{
			QuoteTransactionEventsPojo existingQuoteTransactionEventsPojo = quoteTransactionDAO.findQuoteTransactionEventsById(new Long(
					quoteVO.getEventId()));
			existingQuoteTransactionEventsPojo.setTransactionStatus(BusinessCodes.QUOTE_EVENT_TRANSACTION_STATUS_SUPPLIER_REPLY);
			QuoteTransactionPojo quoteTransactionPojo = existingQuoteTransactionEventsPojo.getQuoteTransactionPojo();
			quoteVO.setQuoteTransactionPojo(quoteTransactionPojo);
			quoteTransactionPojo.setTransactionStatus(BusinessCodes.QUOTE_EVENT_TRANSACTION_STATUS_SUPPLIER_REPLY);
			// Audit User Information
			BaseMBean.updateUserInformation(existingQuoteTransactionEventsPojo, null);
			// Create New Event
			QuoteTransactionEventsPojo newQuoteTransactionEventsPojo = new QuoteTransactionEventsPojo();
			newQuoteTransactionEventsPojo.setSellerComments(quoteVO.getComments());
			newQuoteTransactionEventsPojo.setQuoteTransactionPojo(quoteTransactionPojo);
			if (!quoteVO.getNewQuoteValue().isNaN() || quoteVO.getNewQuoteValue().doubleValue() > 0)
			{
				newQuoteTransactionEventsPojo.setQuoteValue(quoteVO.getNewQuoteValue());
			}
			else
			{
				newQuoteTransactionEventsPojo.setQuoteValue(existingQuoteTransactionEventsPojo.getQuoteValue());
			}
			newQuoteTransactionEventsPojo.setTransactionStatus(BusinessCodes.QUOTE_EVENT_TRANSACTION_STATUS_PENDING);
			FileInfo quoteAttachmentFileInfo = quoteVO.getQuoteAttachmentFileInfo();
			if (quoteAttachmentFileInfo != null)
			{
				newQuoteTransactionEventsPojo.setFileName(quoteAttachmentFileInfo.getFileName());
				newQuoteTransactionEventsPojo.setContentType(quoteAttachmentFileInfo.getContentType());
				Blob blobFileContent = quoteTransactionDAO.getBlob(quoteAttachmentFileInfo.getFile());
				newQuoteTransactionEventsPojo.setFileContent(blobFileContent);
			}
			else
			{
				newQuoteTransactionEventsPojo.setFileName(existingQuoteTransactionEventsPojo.getFileName());
				newQuoteTransactionEventsPojo.setContentType(existingQuoteTransactionEventsPojo.getContentType());
				newQuoteTransactionEventsPojo.setFileContent(existingQuoteTransactionEventsPojo.getFileContent());
			}
			// Audit User Information
			BaseMBean.updateUserInformation(
					newQuoteTransactionEventsPojo,
						existingQuoteTransactionEventsPojo.getModifiedDttm());
			BaseMBean.updateUserInformation(
					quoteTransactionPojo,
						existingQuoteTransactionEventsPojo.getModifiedDttm());

			List<BasePojo> persistentList = new ArrayList<BasePojo>();
			persistentList.add(existingQuoteTransactionEventsPojo);
			persistentList.add(quoteTransactionPojo);
			persistentList.add(newQuoteTransactionEventsPojo);
			quoteVO.setPersistentList(persistentList);
			transactionStatus = quoteTransactionDAO.createQuoteEvent(quoteVO);
		}
		catch (DAOException e)
		{
			log.error(e);
			throw new BusinessException(e);
		}
		return transactionStatus;
	}

	/**
	 * Method to fetch all the QuoteTransactionPojo by transaction status
	 * 
	 * @param buyerMasterPojo
	 * @param List<String> transactionStatusList
	 * @return List<QuoteTransactionPojo>
	 */
	@Override
	public List<QuoteTransactionPojo> getAllQuoteTransactionsForBuyer(BuyerMasterPojo buyerMasterPojo,
			List<String> transactionStatusList) throws BusinessException
	{

		try
		{
			return quoteTransactionDAO.findAllQuoteTransactionPojos(
					buyerMasterPojo,
						transactionStatusList);
		}
		catch (DAOException e)
		{
			log.error(e);
			throw new BusinessException(e);
		}

	}
}
